package com.xiaomaoguai.fcp.pre.kepler.convert.core;

import com.google.common.collect.Maps;
import com.xiaomaoguai.fcp.pre.kepler.convert.core.support.adapter.IConvertMethod;
import com.xiaomaoguai.fcp.pre.kepler.convert.utils.ToStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Map;
import java.util.ServiceLoader;

/**
 * @author WeiHui
 * @version v1.0.0
 * @date 2019/5/27 15:24
 * @since JDK 1.8
 */
@Slf4j
public class ConvertTemplateInvocationHandler implements MethodInterceptor {

	private static final Map<Method, IConvertMethod> METHOD_MAP = Maps.newConcurrentMap();

	public ConvertTemplateInvocationHandler() {
		Method[] methods = ReflectionUtils.getAllDeclaredMethods(ConvertTemplate.class);
		ServiceLoader<IConvertMethod> convertMethods = ServiceLoader.load(IConvertMethod.class);
		convertMethods.forEach(cm -> {
			for (Method method : methods) {
				if (cm.canHandler(method)) {
					METHOD_MAP.put(method, cm);
					break;
				}
			}
		});
		METHOD_MAP.forEach((k, v) -> {
			log.debug("格转模板处理方法映射:方法名:{} ====> 处理类:{}", k.getName(), v.getClass().getName());
		});
	}

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		Method method = invocation.getMethod();
		Object[] args = invocation.getArguments();
		if (ToStringUtils.TO_STRING.equals(method.getName())) {
			return ToStringUtils.handlerToString(this, method, args);
		}
		IConvertMethod convertMethod = METHOD_MAP.get(method);
		if (convertMethod != null) {
			return convertMethod.invoke(method, args);
		}
		throw new IllegalArgumentException(MessageFormat.format("方法:{0}，格转错误，找不到匹配的处理类", method.getName()));
	}

}
